package pl.wroc.uni.ii.evolution.sampleimplementation;

import pl.wroc.uni.ii.evolution.engine.EvAlgorithm;
import pl.wroc.uni.ii.evolution.engine.individuals.EvBinaryVectorIndividual;
import pl.wroc.uni.ii.evolution.engine.operators.general.composition.EvReplacementComposition;
import pl.wroc.uni.ii.evolution.engine.operators.general.composition.EvTwoOperatorsComposition;
import pl.wroc.uni.ii.evolution.engine.operators.general.composition.EvTwoSelectionComposition;
import pl.wroc.uni.ii.evolution.engine.operators.general.display.EvRealtimeToPrintStreamStatistics;
import pl.wroc.uni.ii.evolution.engine.operators.general.replacement.EvBestFromUnionReplacement;
import pl.wroc.uni.ii.evolution.engine.operators.general.selections.EvKBestSelection;
import pl.wroc.uni.ii.evolution.engine.operators.general.selections.EvRandomSelection;
import pl.wroc.uni.ii.evolution.engine.operators.spacespecific.binaryvector.EvBinaryVectorBOAOperator;
import pl.wroc.uni.ii.evolution.engine.operators.spacespecific.binaryvector.EvBinaryVectorNegationMutation;
import pl.wroc.uni.ii.evolution.engine.operators.spacespecific.binaryvector.EvBinaryVectorOnePointCrossover;
import pl.wroc.uni.ii.evolution.engine.operators.spacespecific.binaryvector.EvBinaryVectorUniformCrossover;
import pl.wroc.uni.ii.evolution.engine.operators.spacespecific.binaryvector.boa.bayesnetwork.EvBinaryBayesianNetwork;
import pl.wroc.uni.ii.evolution.engine.operators.spacespecific.binaryvector.boa.metrics.EvBayesianDirchletMetric;
import pl.wroc.uni.ii.evolution.engine.operators.spacespecific.binaryvector.boa.strategies.EvGreedyStrategy;
import pl.wroc.uni.ii.evolution.engine.prototype.EvObjectiveFunction;
import pl.wroc.uni.ii.evolution.engine.prototype.EvTask;
import pl.wroc.uni.ii.evolution.engine.samplealgorithms.EvCGA;
import pl.wroc.uni.ii.evolution.engine.samplealgorithms.EvSGA;
import pl.wroc.uni.ii.evolution.engine.terminationconditions.EvBestValueNotImproved;
import pl.wroc.uni.ii.evolution.engine.terminationconditions.EvMaxIteration;
import pl.wroc.uni.ii.evolution.objectivefunctions.EvKDeceptiveOneMax;
import pl.wroc.uni.ii.evolution.objectivefunctions.EvOneMax;
import pl.wroc.uni.ii.evolution.solutionspaces.EvBinaryVectorSpace;

public class EvOneMaxExample {

  /**
   * Example of use OneMax (and also GenericEvolutionaryAlgorithm).
   * @param no default parameters
   */
  public static void main(String[] args) {
    
    EvObjectiveFunction<EvBinaryVectorIndividual> objective_function = new EvOneMax();
    
    EvCGA cga = new EvCGA(0.04);
    cga.setSolutionSpace(new EvBinaryVectorSpace(objective_function,30));
    cga.setObjectiveFunction(objective_function); 
    cga.setTerminationCondition(new EvMaxIteration<EvBinaryVectorIndividual>(1500));
 
    
    EvTask evolutionary_task = new EvTask();
    evolutionary_task.setAlgorithm(cga);
    evolutionary_task.run();
    evolutionary_task.printBestResult();
    
    
    
    EvAlgorithm<EvBinaryVectorIndividual> genericEA = new EvAlgorithm<EvBinaryVectorIndividual>(100);
    genericEA.setSolutionSpace(new EvBinaryVectorSpace(objective_function,30));
    genericEA.setObjectiveFunction(objective_function);
    genericEA.addOperator(new EvKBestSelection<EvBinaryVectorIndividual>(50));
    genericEA.addOperator(new EvBinaryVectorUniformCrossover());
    genericEA.setTerminationCondition(new EvMaxIteration<EvBinaryVectorIndividual>(100));
   
    evolutionary_task.setAlgorithm(genericEA);
    evolutionary_task.run();
    evolutionary_task.printBestResult();
    
    genericEA = new EvAlgorithm<EvBinaryVectorIndividual>(1000);
    genericEA.setSolutionSpace(new EvBinaryVectorSpace(objective_function, 30));
    genericEA.setObjectiveFunction(new EvKDeceptiveOneMax(4));
    genericEA.addOperator(new EvReplacementComposition<EvBinaryVectorIndividual>(
        new EvBinaryVectorBOAOperator<EvBinaryVectorIndividual>(
            new EvBinaryBayesianNetwork(4),
            new EvBayesianDirchletMetric(),
            new EvGreedyStrategy<EvBinaryVectorIndividual>(10),
            100),
        new EvBestFromUnionReplacement<EvBinaryVectorIndividual>())); 
  
    genericEA.setTerminationCondition(new EvMaxIteration<EvBinaryVectorIndividual>(1));

   
    evolutionary_task.setAlgorithm(genericEA);
    evolutionary_task.run();
    evolutionary_task.printBestResult();
    
   
    System.out.println("--==SGA==---");
    
    EvAlgorithm<EvBinaryVectorIndividual> sga = new EvSGA<EvBinaryVectorIndividual>(100,
             new EvTwoSelectionComposition<EvBinaryVectorIndividual>( 
                 new EvRandomSelection<EvBinaryVectorIndividual>(16, false),
                 new EvKBestSelection<EvBinaryVectorIndividual>(4)),
             new EvTwoOperatorsComposition<EvBinaryVectorIndividual>(
                 new EvBinaryVectorNegationMutation(0.02), new EvBinaryVectorOnePointCrossover()),
             new EvBestFromUnionReplacement<EvBinaryVectorIndividual>());
             
    
    
    sga.setSolutionSpace(new EvBinaryVectorSpace(new EvOneMax(), 30));
    sga.addOperator(new EvRealtimeToPrintStreamStatistics<EvBinaryVectorIndividual>(System.out));
    sga.setTerminationCondition(new EvBestValueNotImproved<EvBinaryVectorIndividual>(4));
    evolutionary_task.setAlgorithm(sga);
    evolutionary_task.run();
    evolutionary_task.printBestResult();
  }

}
